package com.interactive.internal.ant;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.apache.tools.ant.Task;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

/**
 * Abstract task for modifying the classpath element of the launch tag in an
 * abbot script.
 *
 * <p>Title: AbstractAbbotClasspathTask</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: Interactive Network Technologies Inc.</p>
 *
 * @author John Januskey (john@int.com)
 * @version 1.0
 **/
public abstract class AbstractAbbotClassPathTask extends Task
{
  public abstract void setTestHome(String testHome);

  /**
   * Returns the string for the root directory to look for scripts.
   *
   * @return String
   */
  protected abstract String getHomeDir();

  /**
   * Returns the value that will be injected into the scripts classpath.
   *
   * @return String
   */
  protected abstract String getClasspathValue();

  public void execute()
  {
    List files = AbbotTestSuite.findTestScripts(new File(getHomeDir()));
    AbbotTestFixture.removeNonAbbotFiles(files);

    Iterator iter = files.iterator();
    SAXBuilder builder = new SAXBuilder();
    XMLOutputter outputter = new XMLOutputter();

    while (iter.hasNext())
    {
      File file = new File(iter.next().toString());

      try
      {
        Document doc = builder.build(file);
        Element launchElement = findElement("launch", doc.getRootElement());
        launchElement.setAttribute("classpath", getClasspathValue());

        FileOutputStream ostream = new FileOutputStream(file);
        outputter.output(doc, ostream);
        ostream.flush();
        ostream.close();
      }
      catch (IOException ex)
      {
        throw new RuntimeException("File access error " + file.getName() + ex);
      }
      catch (JDOMException ex)
      {
        throw new RuntimeException("Failed to parse file " + file.getName() + ex);
      }
    }
  }

  /**
   * findElement
   *
   * @param string String
   * @param doc Document
   * @return Element
   */
  protected static Element findElement(String targetElementName,
                                       Element element)
  {
    List children = element.getChildren();
    Iterator iter = children.iterator();
    Element targetElement = null;

    while (iter.hasNext())
    {
      Element child = (Element) iter.next();
      if (child.getName().equals(targetElementName))
      {
        return child;
      }
      else
      {
        targetElement = findElement(targetElementName, child);
        if (targetElement != null)
        {
          return targetElement;
        }
      }
    }
    return null;
  }

}
